package com.examplee.puzle;

import android.content.ClipData;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.app.Activity;
import android.view.DragEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;


public class MainActivity extends Activity implements View.OnTouchListener {

    static MainActivity ActivityMain;
    Tablero tablero = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int num_piezas = 9;

        ActivityMain = this;

        tablero = new Tablero(num_piezas);
       
        String imgsel;
        Bundle extras;
        extras=getIntent().getExtras();
        if(extras==null){
        	imgsel=null;
        }else{
        	imgsel=extras.getString("imagen");
        }
        int res_imagen=getResources().getIdentifier(imgsel, "drawable", getPackageName());
        ImageView imgview1=(ImageView)findViewById(R.id.imageView10);
        imgview1.setImageResource(res_imagen);
        /*
        Recupero la imagen
        Escalo la imagen
        Troceo la imagen
         */
        //Bitmap foto = BitmapFactory.decodeResource(getResources(), R.drawable.peppapig);
        Bitmap foto = BitmapFactory.decodeResource(getResources(), res_imagen);
        foto = escalarImagen(foto, 480, 320);
        Bitmap[] piezas = splitBitmap(foto);

        tablero.formarTablero(piezas);
        pintarTablero(tablero, num_piezas);
        Coordenadas coordenadas_blanca = tablero.encontrarFichaBlanca();
        aplicarOnDrag(coordenadas_blanca, tablero.getTamano());
        aplicarOnTouch(coordenadas_blanca, tablero.getTamano());	
    }

    void aplicarOnDrag(Coordenadas blanca, int tamano){
        int id = (int)(Math.sqrt(tamano)) * blanca.getI() + blanca.getJ() + 1;
        String cadena = "imageView" + id;
        int idResource = getResources().getIdentifier(cadena, "id", getPackageName());
        findViewById(idResource).setOnDragListener(new MiDrag());
    }

    public static MainActivity getInstance(){
        return ActivityMain;
    }

    void aplicarOnTouch(Coordenadas blanca, int tamano){
    	int id = (int)(Math.sqrt(tamano)) * blanca.getI() + blanca.getJ() + 1;
        //Norte
        if(blanca.getI() != 0){ 
            String cadena = "imageView" + (id-3);
            int idResource = getResources().getIdentifier(cadena, "id", getPackageName());
            findViewById(idResource).setOnTouchListener(this);
        }

        //Este
        if(blanca.getJ()<(int)(Math.sqrt(tamano))-1){
            String cadena = "imageView" + (id+1);
            int idResource = getResources().getIdentifier(cadena, "id", getPackageName());
            findViewById(idResource).setOnTouchListener(this);
        }

        //Sur
        if(blanca.getI()<(int)(Math.sqrt(tamano))-1){
            String cadena = "imageView" + (id+3);
            int idResource = getResources().getIdentifier(cadena, "id", getPackageName());
            findViewById(idResource).setOnTouchListener(this);
        }

        //Oeste
        if(blanca.getJ() != 0){
            String cadena = "imageView" + (id-1);
            int idResource = getResources().getIdentifier(cadena, "id", getPackageName());
            findViewById(idResource).setOnTouchListener(this);
        }

    }

    /*
    Recupero el Bitmap que tiene la ficha y se lo asigno a la vista.
     */

    void pintarTablero(Tablero tablero, int num){

        for(int i=0; i<num; i++){
            String cadena = "imageView" + (i+1);
            int idResource = getResources().getIdentifier(cadena, "id", getPackageName());
            Bitmap foto = tablero.getFicha(i).getFoto();
            ((ImageView)findViewById(idResource)).setImageBitmap(foto);
        }


    }

    // Metodo que divide una imagen en 9 trozos.
    public Bitmap[] splitBitmap(Bitmap picture){
        int ancho = picture.getWidth();
        int alto = picture.getHeight();
        int tercioancho = ancho/3;
        int dosterciosancho = tercioancho * 2;

        int tercioalto = alto/3;
        int dosterciosalto = tercioalto *2;

        Bitmap scaledBitmap = Bitmap.createScaledBitmap(picture, ancho, alto, true);
        Bitmap[] imgs = new Bitmap[9];

        imgs[0] = Bitmap.createBitmap(scaledBitmap, 0, 0, tercioancho , tercioalto);
        imgs[1] = Bitmap.createBitmap(scaledBitmap, tercioancho, 0, tercioancho, tercioalto);
        imgs[2] = Bitmap.createBitmap(scaledBitmap, dosterciosancho, 0, tercioancho, tercioalto);
        imgs[3] = Bitmap.createBitmap(scaledBitmap, 0, tercioalto, tercioancho, tercioalto);
        imgs[4] = Bitmap.createBitmap(scaledBitmap, tercioancho, tercioalto, tercioancho,tercioalto);
        imgs[5] = Bitmap.createBitmap(scaledBitmap, dosterciosancho, tercioalto,tercioancho,tercioalto);
        imgs[6] = Bitmap.createBitmap(scaledBitmap, 0, dosterciosalto, tercioancho , tercioalto);
        imgs[7] = Bitmap.createBitmap(scaledBitmap, tercioancho, dosterciosalto, tercioancho, tercioalto);
        // Pieza blanca que sobra en el 9puzzle
        Bitmap pieza_blanca = BitmapFactory.decodeResource(getResources(), R.drawable.casillablanca);
        ancho = pieza_blanca.getWidth();
        alto = pieza_blanca.getHeight();
        Bitmap pieza_blanca2 = Bitmap.createScaledBitmap(pieza_blanca, 200, 200, true);
        imgs[8] = Bitmap.createBitmap(pieza_blanca2, 0, 0,tercioancho,tercioalto);
        return imgs;
    }


    public boolean onTouch(View objeto, MotionEvent evento){
        /* He cambiado en el manifest el mininmo API level de 7 a 11 porque este metodo
        es para nuevas versiones de Android.
         */
        if(evento.getAction() == MotionEvent.ACTION_DOWN){
            ClipData datos = ClipData.newPlainText("","");
            View.DragShadowBuilder objeto_sombra = new View.DragShadowBuilder(objeto);
            objeto.startDrag(datos, objeto_sombra, objeto, 0);
            objeto.setVisibility(View.INVISIBLE);
            return true;
        }
        else{
            return false;
        }
    }

    /*
    Mi metodo escala la imagen a las medidas que le proporcione.
     */

    public static Bitmap escalarImagen(Bitmap BitmapOrg, int w, int h) {
        int width;
        width = BitmapOrg.getWidth();
        int height;
        height = BitmapOrg.getHeight();
        // calculamos el escalado de la imagen destino
        float scaleWidth = ((float) w) / width;
        float scaleHeight = ((float) h) / height;
        // para poder manipular la imagen
        // debemos crear una matriz
        Matrix matrix = new Matrix();
        // resize the Bitmap
        matrix.postScale(scaleWidth, scaleHeight);
        // volvemos a crear la imagen con los nuevos valores
        return Bitmap.createBitmap(BitmapOrg, 0, 0, width, height, matrix, true);
    }


    Tablero getTablero(){
        return this.tablero;
    }

    void quitarListener(){
    	for(int i=1; i<=tablero.getTamano(); i++){
            String cadena = "imageView" + (i);
            int idResource = getResources().getIdentifier(cadena, "id", getPackageName());
            findViewById(idResource).setOnTouchListener(null);
            findViewById(idResource).setOnDragListener(null);
    	}
    	
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}

final class MiDrag implements View.OnDragListener{

    Tablero juego = MainActivity.getInstance().getTablero();
    /* El metodo onDrag es el encargado de mover la imagen que se esta desplazando
    a la casilla 'en blanco' y viceversa...
     */
    public boolean onDrag(View imagen_blanca, DragEvent dragEvent) {

         switch (dragEvent.getAction()){
             case DragEvent.ACTION_DRAG_ENTERED:
                 break;
             case DragEvent.ACTION_DRAG_EXITED:
                 break;
             case DragEvent.ACTION_DRAG_ENDED:
            	 View imagen_desplazada = (View) dragEvent.getLocalState();
            	 imagen_desplazada.setVisibility(View.VISIBLE);
            	 break;
             case DragEvent.ACTION_DROP:
	            View imagen_desplazada1 = (View) dragEvent.getLocalState();
	            intercambioFichas(imagen_desplazada1, imagen_blanca);
	            imagen_desplazada1.setVisibility(View.VISIBLE);
	            break;
         }
            if(juego.estaResuelto())
                Toast.makeText(imagen_blanca.getContext(), "PUZZLE RESUELTO", Toast.LENGTH_LONG).show();

        return true;
}
    
    void intercambioID(View imagen_desplazada, View imagen_blanca){
        Tablero tablero = MainActivity.getInstance().getTablero();
        int id_desplazada = (Integer) imagen_desplazada.getTag();
        int id_blanca = -1;

        Ficha ficha_desplazada = tablero.getFichaPorID(id_desplazada);
        Ficha ficha_blanca = tablero.getFichaPorID(id_blanca);


        /*
        Cambio las fichas
         */
        tablero.cambiarFichas(ficha_blanca, ficha_desplazada);	
    }
    
    void intercambioImageView(View imagen_desplazada, View imagen_blanca){
    	/*        
        Cambio las imagenes
         */
    	ImageView blanca = (ImageView) imagen_blanca;
    	ImageView desplazada = (ImageView) imagen_desplazada;
    	Drawable aux = blanca.getDrawable();
    	blanca.setImageDrawable(desplazada.getDrawable());
    	desplazada.setImageDrawable(aux);
    	
    	/*
    	 * Cambio los tags
    	 */
    	
    	blanca.setTag(desplazada.getTag());
    	desplazada.setTag(-1);
    	
    	
        ViewGroup papa_blanca = (ViewGroup) imagen_blanca.getParent();
        ViewGroup papa_desplazada = (ViewGroup) imagen_desplazada.getParent();
        papa_blanca.removeView(imagen_blanca);
        papa_desplazada.removeView(imagen_desplazada);
        papa_desplazada.addView(desplazada);
        papa_blanca.addView(blanca);
        
    }

    void intercambioFichas(View imagen_desplazada, View imagen_blanca){

    	intercambioID(imagen_desplazada, imagen_blanca);
    	intercambioImageView(imagen_desplazada, imagen_blanca);
    	
    	MainActivity activity = MainActivity.getInstance();
    	Coordenadas blanca = activity.getTablero().encontrarFichaBlanca();
    	// Quito todos los touch
    	activity.quitarListener();
    	// Aplico los nuevos touch
        activity.aplicarOnTouch(blanca, activity.getTablero().getTamano());
        activity.aplicarOnDrag(blanca, activity.getTablero().getTamano());

    }


        }

